package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.mapper.YgCommissionMapper;
import com.ygqh.baby.mapper.YgUserBalanceDetailMapper;
import com.ygqh.baby.mapper.YgUserBankMapper;
import com.ygqh.baby.model.YgCommissionModel;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.YgCommissionDetailService;
import com.ygqh.baby.service.YgCommissionService;
import com.ygqh.baby.service.YgFrameCodeService;
import com.ygqh.baby.service.YgUserBalanceService;
import com.ygqh.baby.service.task.YgAsynClient;
import com.ygqh.baby.utils.YgStringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class YgCommissionServiceImpl implements YgCommissionService {

	Logger logger = Logger.getLogger(YgCommissionService.class);

	@Autowired
	private YgCommissionMapper ygCommissionMapper;
	@Autowired
	private YgUserBankMapper ygUserBankMapper;
	@Autowired
	private YgUserBalanceService balanceService;
	@Autowired
	private YgUserBalanceDetailMapper userBalanceDetailMapper;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgCommissionDetailService ygCommissionDetailService;
	@Autowired
	private YgAsynClient sendMailSyncClient;
	

	@Override
	public List<YgCommission> find(Long userId) {
		YgCommissionExample example = new YgCommissionExample();
		example.createCriteria().andUserIdEqualTo(userId);
		return ygCommissionMapper.selectByExample(example);
	}

	@Override
	public int findCount(Long userId) {
		YgCommissionExample example = new YgCommissionExample();
		example.createCriteria().andUserIdEqualTo(userId);
		return ygCommissionMapper.countByExample(example);
	}

	@Override
	public YgCommission findById(Long id) {
		return ygCommissionMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgCommission ygCommission) {
		return ygCommissionMapper.insertSelective(ygCommission);
	}

	@Override
	public int update(YgCommission ygCommission) {
		return ygCommissionMapper.updateByPrimaryKeySelective(ygCommission);
	}

	@Override
	public ResultSet<YgCommission> search(QueryInfo queryInfo, String userName, CommissionStatus status, String q) {
		List<YgCommission> list = ygCommissionMapper.selectSuper(queryInfo, userName, status, q);
		int count = ygCommissionMapper.countSuper(userName, status, q);
		ResultSet<YgCommission> resultSet = new ResultSet<YgCommission>(count, list);
		return resultSet;
	}

	@Override
	public int saveOrUpdate(YgCommission ygCommission) {
		int r = 0;
		if (ygCommission.getId() != null) {
			r = this.update(ygCommission);
		} else {
			r = this.save(ygCommission);
		}
		return r;
	}

	@Override
	public YgUserBank findUserBank(Long userId) {
		YgUserBankExample example = new YgUserBankExample();
		example.createCriteria().andUserIdEqualTo(userId);
		List<YgUserBank> list = ygUserBankMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public int bindBank(Long userId, Long bankId, String bankAccount, String bankName, String bankBranch, String bankNo, String alipayCode) {

		YgUserBank record = new YgUserBank();
		record.setId(bankId);
		record.setUserId(userId);
		record.setBankAccount(bankAccount);
		record.setBankBranch(bankBranch);
		record.setBankNo(bankNo);
		record.setBankName(bankName);
		record.setAlipayCode(alipayCode);
		if (bankId != null) {
			record.setCreateTime(new Date());
			return ygUserBankMapper.updateByPrimaryKeySelective(record);
		} else {
			record.setUpdateTime(new Date());
			return ygUserBankMapper.insertSelective(record);
		}

	}

	@Override
	public YgUserBank findBankInfo(Long userId) {
		YgUserBankExample example = new YgUserBankExample();
		example.createCriteria().andUserIdEqualTo(userId);
		List<YgUserBank> list = ygUserBankMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public int applyWithdrawals(Long userId, String userName, BigDecimal commissionPrice) {
		return applyWithdrawals(userId, userName, commissionPrice, Constant.YIIGOO_PLATFORM_NO);
	}

	@Override
	public int applyWithdrawals(Long userId, String userName, BigDecimal commissionPrice, String platformNo) {
		Assert.notNull(userId);
		Assert.notNull(commissionPrice);
		YgCommission ygCommission = new YgCommission();
		ygCommission.setUserId(userId);
		ygCommission.setCommissionCode(YgStringUtils.getRandomString(20));
		ygCommission.setCommissionPrice(commissionPrice);
		ygCommission.setCommissionStatus(CommissionStatus.WaitingPay);
		ygCommission.setPlatformNo(platformNo);
		ygCommission.setCreateBy(userName);
		ygCommission.setCreateTime(new Date());
		return this.save(ygCommission);
	}

	@Override
	public ResultSet<YgCommissionModel> searchModel(QueryInfo queryInfo, Long userId, String[] commissionStatus) {
		return searchModel(queryInfo, userId, commissionStatus, Constant.YIIGOO_PLATFORM_NO);
	}

	@Override
	public ResultSet<YgCommissionModel> searchModel(QueryInfo queryInfo, Long userId, String[] commissionStatus,
													String platformNo) {
		List<YgCommissionModel> list = ygCommissionMapper.searchModel(queryInfo, userId, commissionStatus, platformNo);
		int count = ygCommissionMapper.searchModelCount(userId, commissionStatus, platformNo);
		return new ResultSet<>(count, list);
	}

	@Override
	public Message withdraw(YgUser user, BigDecimal money) throws Exception {
		return withdraw(user, money, Constant.YIIGOO_PLATFORM_NO);
	}

	@Override
	public Message withdraw(YgUser user, BigDecimal money, String platformNo) throws Exception {
		YgUserBank bank = findBankInfo(user.getId());
		if (bank == null) {
			return Message.error("请先绑定银行卡", null);
		}
		if (money.compareTo(new BigDecimal(100)) < 0) {
			return Message.error("提现金额需大于100元", null);
		}
		YgUserBalance balance = balanceService.findByUserId(user.getId());
		if (money.compareTo(balance.getBalancePrice()) > 0) {
			return Message.error("提现金额不能大于可提现金额", null);
		}

		Map<String, Object> map = balanceService.findTotalBalancePriceForCommission(user.getId(), null);
		BigDecimal price = (BigDecimal) map.get("balance_price");
		Long maxId = (Long) map.get("max_id");
		if (money.compareTo(price) != 0) {
			throw new Exception("可提现金额与提现金额不相等");
		}

		YgCommission commission = new YgCommission();
		commission.setUserId(user.getId());

		String commissionCode = "SQ" + ygFrameCodeService.getFrameCode(CodeType.SQCode, new Date());
		commission.setCommissionCode(commissionCode);
		commission.setCreateBy(user.getUserName());
		commission.setCommissionPrice(money);
		commission.setCommissionStatus(CommissionStatus.WaitingPay);
		commission.setCreateTime(new Date());
		commission.setPlatformNo(platformNo);
		try {
			// 提交申请单
			this.save(commission);
			opWithdrawDetail(commission.getId(), commission.getCommissionCode(), balance, money, null, platformNo);

			ygCommissionDetailService.updateBalanceDetailByCommission(user.getId(), commission.getId(), money,
					CommissionStatus.WaitingPay, maxId, null);
			sendMailSyncClient.syncCommissionDetail(commissionCode);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("用户id=" + user.getId() + ",提现申请失败");
			throw e;
		}

		return Message.success("提现成功");
	}

	public void opWithdrawDetail(Long commissionId, String commissionCode, YgUserBalance balance, BigDecimal money,
								 String remark, String platformNo) {
		// 扣减可提现金额
		balance.setBalancePrice(balance.getBalancePrice().subtract(money));
		// 增加已提现金额
		balance.setWithdrawPrice(balance.getWithdrawPrice().add(money));
		balance.setUpdateTime(new Date());
		balanceService.update(balance);

		// 写入可提现流水
		YgUserBalanceDetail detail = new YgUserBalanceDetail();
		detail.setUserId(balance.getUserId());
		detail.setId(null);
		detail.setOrderId(commissionCode);
		detail.setBalancePrice(new BigDecimal(0).subtract(money));
		detail.setCreateTime(new Date());
		detail.setCommissionRate(new BigDecimal(0));
		detail.setOrderPrice(new BigDecimal(0));
		detail.setCommissionId(commissionId);
		detail.setCommissionStatus(CommissionStatus.WaitingPay);
		detail.setOperation(OperationType.Withdraw.getTitle());
		detail.setOperationType(OperationType.Withdraw);
		detail.setPriceType(BalanceType.Balance);
		detail.setRemark(remark);
		detail.setPlatformNo(platformNo);
		userBalanceDetailMapper.insert(detail);
	}

	@Override
	public YgCommissionModel findModelById(Long id) {
		return ygCommissionMapper.findModelById(id);
	}

	@Override
	public int updateWithdrawStatus(Long commissionId, CommissionStatus commissionStatus, String remark) {
		YgCommission commission = this.findById(commissionId);
		commission.setCommissionStatus(commissionStatus);
		commission.setRemark(remark);
		// 打款失败要把流水归还
		if (commissionStatus.equals(CommissionStatus.PayError)) {
			YgUserBalance balance = balanceService.findByUserId(commission.getUserId());
			// 归还 增加可提现金额
			balance.setBalancePrice(balance.getBalancePrice().add(commission.getCommissionPrice()));
			// 归还 减去已提现金额
			balance.setWithdrawPrice(balance.getWithdrawPrice().subtract(commission.getCommissionPrice()));
			balance.setUpdateTime(new Date());
			balanceService.update(balance);
			YgUserBalanceDetail detail = new YgUserBalanceDetail();
			detail.setId(null);
			detail.setUserId(commission.getUserId());
			detail.setOrderId(commission.getCommissionCode());
			detail.setBalancePrice(commission.getCommissionPrice());
			detail.setCreateTime(new Date());
			detail.setCommissionRate(new BigDecimal(0));
			detail.setCommissionId(commissionId);
			detail.setCommissionStatus(commissionStatus);
			detail.setOrderPrice(new BigDecimal(0));
			detail.setPriceType(BalanceType.Balance);
			detail.setOperation(OperationType.WithdrawFail.getTitle());
			detail.setOperationType(OperationType.WithdrawFail);
			detail.setPlatformNo(commission.getPlatformNo());
			userBalanceDetailMapper.insert(detail);
		}
		// 回写可提现明细申请单状态
		balanceService.updateBalanceDetailByCommission(commission.getUserId(), commissionId, commissionStatus,
				false, null, commission.getPlatformNo());
		return this.update(commission);
	}

	@Override
	public void opWithdrawDetail(YgUserBalance balance, BigDecimal money, String remark) {
		// TODO Auto-generated method stub

	}

}
